<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, height=device-height, initial-scale=1, user-scalable=no">
  <meta name="description" content="API docs for the computeManifests function from the media library, for the Dart programming language.">
  <title>computeManifests function - media library - Dart API</title>


  
  <link rel="preconnect" href="https://fonts.gstatic.com">
  <link href="https://fonts.googleapis.com/css2?family=Roboto+Mono:ital,wght@0,300;0,400;0,500;0,700;1,400&display=swap" rel="stylesheet">
  <link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@48,400,0,0" rel="stylesheet">
  
  <link rel="stylesheet" href="../static-assets/github.css?v1">
  <link rel="stylesheet" href="../static-assets/styles.css?v1">
  <link rel="icon" href="../static-assets/favicon.png?v1">

  
</head>


<body data-base-href="../" data-using-base-href="false" class="light-theme">

<div id="overlay-under-drawer"></div>

<header id="title">
  <span id="sidenav-left-toggle" class="material-symbols-outlined" role="button" tabindex="0">menu</span>
  <ol class="breadcrumbs gt-separated dark hidden-xs">
    <li><a href="../index.html">yuuna</a></li>
    <li><a href="../media/media-library.html">media</a></li>
    <li class="self-crumb">computeManifests function</li>
  </ol>
  <div class="self-name">computeManifests</div>
  <form class="search navbar-right" role="search">
    <input type="text" id="search-box" autocomplete="off" disabled class="form-control typeahead" placeholder="Loading search...">
  </form>
  <div class="toggle" id="theme-button">
    <label for="theme">
      <input type="checkbox" id="theme" value="light-theme">
      <span id="dark-theme-button" class="material-symbols-outlined">
        brightness_4
      </span>
      <span id="light-theme-button" class="material-symbols-outlined">
        brightness_5
      </span>
    </label>
  </div>
</header>
<main>

  <div id="dartdoc-main-content" class="main-content">
      <div>
<h1><span class="kind-function">computeManifests</span> function 
 
</h1></div>

    <section class="multi-line-signature">
        

<span class="returntype"><a href="https://api.flutter.dev/flutter/dart-async/Future-class.html">Future</a><span class="signature">&lt;<wbr><span class="type-parameter"><a href="../media/VideoManifest-class.html">VideoManifest</a></span>&gt;</span></span>
<span class="name ">computeManifests</span>(<wbr><ol class="parameter-list"><li><span class="parameter" id="computeManifests-param-params"><span class="type-annotation"><a href="../media/ComputeManifestParams-class.html">ComputeManifestParams</a></span> <span class="parameter-name">params</span></span></li>
</ol>)

        

    </section>
    
<section class="desc markdown">
  <p>Used to be able to get both manifests at the same time.</p>
</section>


    
<section class="summary source-code" id="source">
  <h2><span>Implementation</span></h2>
  <pre class="language-dart"><code class="language-dart">Future&lt;VideoManifest&gt; computeManifests(ComputeManifestParams params) async {
  YoutubeExplode yt = YoutubeExplode();

  List&lt;Future&gt; futures = [
    yt.videos.streamsClient.getManifest(params.videoId),
  ];
  if (params.closedCaptionsManifest == null) {
    futures.add(yt.videos.closedCaptions.getManifest(
      params.videoId,
      formats: [ClosedCaptionFormat.vtt],
    ));
  }

  final manifests = await Future.wait(futures);
  StreamManifest streamManifest = manifests.elementAt(0) as StreamManifest;
  late ClosedCaptionManifest closedCaptionManifest;

  if (params.closedCaptionsManifest != null) {
    closedCaptionManifest = params.closedCaptionsManifest!;
  } else {
    closedCaptionManifest = manifests.elementAt(1) as ClosedCaptionManifest;
  }

  Map&lt;String, ClosedCaptionTrackInfo&gt; tracksByLanguage = {};
  List&lt;ClosedCaptionTrackInfo&gt; ccTracks =
      closedCaptionManifest.tracks.where((e) =&gt; !e.isAutoGenerated).toList();
  List&lt;ClosedCaptionTrackInfo&gt; autoTracks =
      closedCaptionManifest.tracks.where((e) =&gt; e.isAutoGenerated).toList();

  for (ClosedCaptionTrackInfo track in [...ccTracks, ...autoTracks]) {
    String shortCode = track.language.code.substring(0, 2);
    tracksByLanguage.putIfAbsent(shortCode, () =&gt; track);
  }

  List&lt;MapEntry&lt;String, String&gt;&gt; entries = [];

  if (!params.subtitlesCached) {
    entries.addAll(
      await Future.wait(
        tracksByLanguage.values.map(
          (trackInfo) async {
            String shortCode = trackInfo.language.code.substring(0, 2);
            String subtitles =
                await yt.videos.closedCaptions.getSubTitles(trackInfo);

            if (trackInfo.isAutoGenerated) {
              subtitles = subtitles.replaceAllMapped(vttRegex, (match) {
                String text = match.group(11) ?? &#39;&#39;;
                List&lt;String&gt; lines = text.split(&#39;\n&#39;);

                String currentSubtitle =
                    subtitles.substring(match.start, match.end);
                int position = currentSubtitle
                    .lastIndexOf(text)
                    .clamp(0, currentSubtitle.length);

                String newSubtitle = currentSubtitle.replaceFirst(
                    text, lines.last.trim(), position);

                return newSubtitle;
              });
            }

            String metadata = trackInfo.isAutoGenerated
                ? &#39;YouTube - Auto - [$shortCode]&#39;
                : &#39;YouTube - CC - [$shortCode]&#39;;

            return MapEntry(metadata, subtitles);
          },
        ),
      ),
    );
  }

  Map&lt;String, String&gt; subtitlesByLanguageCache = {};
  for (MapEntry&lt;String, String&gt; entry in entries) {
    subtitlesByLanguageCache.putIfAbsent(entry.key, () =&gt; entry.value);
  }

  return VideoManifest(
    streamManifest: streamManifest,
    closedCaptionManifest: closedCaptionManifest,
    subtitlesByLanguageCache: subtitlesByLanguageCache,
  );
}</code></pre>
</section>


  </div> <!-- /.main-content -->

  <div id="dartdoc-sidebar-left" class="sidebar sidebar-offcanvas-left">
    <header id="header-search-sidebar" class="hidden-l">
  <form class="search-sidebar" role="search">
    <input type="text" id="search-sidebar" autocomplete="off" disabled class="form-control typeahead" placeholder="Loading search...">
  </form>
</header>

<ol class="breadcrumbs gt-separated dark hidden-l" id="sidebar-nav">
  <li><a href="../index.html">yuuna</a></li>
  <li><a href="../media/media-library.html">media</a></li>
  <li class="self-crumb">computeManifests function</li>
</ol>


    <h5>media library</h5>
    <ol>
      <li class="section-title"><a href="../media/media-library.html#classes">Classes</a></li>
        <li><a href="../media/ComputeManifestParams-class.html">ComputeManifestParams</a></li>
        <li><a href="../media/DictionaryMediaType-class.html">DictionaryMediaType</a></li>
        <li><a href="../media/MediaItem-class.html">MediaItem</a></li>
        <li><a href="../media/MediaSource-class.html">MediaSource</a></li>
        <li><a href="../media/MediaType-class.html">MediaType</a></li>
        <li><a href="../media/PlayerLocalMediaSource-class.html">PlayerLocalMediaSource</a></li>
        <li><a href="../media/PlayerMediaSource-class.html">PlayerMediaSource</a></li>
        <li><a href="../media/PlayerMediaType-class.html">PlayerMediaType</a></li>
        <li><a href="../media/PlayerNetworkStreamSource-class.html">PlayerNetworkStreamSource</a></li>
        <li><a href="../media/PlayerYoutubeSource-class.html">PlayerYoutubeSource</a></li>
        <li><a href="../media/ReaderBrowserSource-class.html">ReaderBrowserSource</a></li>
        <li><a href="../media/ReaderChatgptSource-class.html">ReaderChatgptSource</a></li>
        <li><a href="../media/ReaderClipboardSource-class.html">ReaderClipboardSource</a></li>
        <li><a href="../media/ReaderLyricsSource-class.html">ReaderLyricsSource</a></li>
        <li><a href="../media/ReaderMediaSource-class.html">ReaderMediaSource</a></li>
        <li><a href="../media/ReaderMediaType-class.html">ReaderMediaType</a></li>
        <li><a href="../media/ReaderMokuroSource-class.html">ReaderMokuroSource</a></li>
        <li><a href="../media/ReaderTtuSource-class.html">ReaderTtuSource</a></li>
        <li><a href="../media/ReaderWebsocketSource-class.html">ReaderWebsocketSource</a></li>
        <li><a href="../media/VideoManifest-class.html">VideoManifest</a></li>
        <li><a href="../media/ViewerCameraSource-class.html">ViewerCameraSource</a></li>
        <li><a href="../media/ViewerMediaSource-class.html">ViewerMediaSource</a></li>
        <li><a href="../media/ViewerMediaType-class.html">ViewerMediaType</a></li>

      <li class="section-title"><a href="../media/media-library.html#extensions">Extensions</a></li>
        <li><a href="../media/GetMediaItemCollection.html">GetMediaItemCollection</a></li>
        <li><a href="../media/MediaItemByIndex.html">MediaItemByIndex</a></li>
        <li><a href="../media/MediaItemQueryFilter.html">MediaItemQueryFilter</a></li>
        <li><a href="../media/MediaItemQueryLinks.html">MediaItemQueryLinks</a></li>
        <li><a href="../media/MediaItemQueryObject.html">MediaItemQueryObject</a></li>
        <li><a href="../media/MediaItemQueryProperty.html">MediaItemQueryProperty</a></li>
        <li><a href="../media/MediaItemQuerySortBy.html">MediaItemQuerySortBy</a></li>
        <li><a href="../media/MediaItemQuerySortThenBy.html">MediaItemQuerySortThenBy</a></li>
        <li><a href="../media/MediaItemQueryWhere.html">MediaItemQueryWhere</a></li>
        <li><a href="../media/MediaItemQueryWhereDistinct.html">MediaItemQueryWhereDistinct</a></li>
        <li><a href="../media/MediaItemQueryWhereSort.html">MediaItemQueryWhereSort</a></li>


      <li class="section-title"><a href="../media/media-library.html#constants">Constants</a></li>
        <li><a href="../media/MediaItemSchema-constant.html">MediaItemSchema</a></li>

      <li class="section-title"><a href="../media/media-library.html#properties">Properties</a></li>
        <li><a href="../media/channelProvider.html">channelProvider</a></li>
        <li><a href="../media/clipboardProvider.html">clipboardProvider</a></li>
        <li><a href="../media/commentsProvider.html">commentsProvider</a></li>
        <li><a href="../media/lyricsPermissionsProvider.html">lyricsPermissionsProvider</a></li>
        <li><a href="../media/lyricsProvider.html">lyricsProvider</a></li>
        <li><a href="../media/lyricsStreamProvider.html">lyricsStreamProvider</a></li>
        <li><a href="../media/repliesProvider.html">repliesProvider</a></li>
        <li><a href="../media/ttuBooksProvider.html">ttuBooksProvider</a></li>
        <li><a href="../media/ttuServerProvider.html">ttuServerProvider</a></li>
        <li><a href="../media/vttRegex.html">vttRegex</a></li>

      <li class="section-title"><a href="../media/media-library.html#functions">Functions</a></li>
        <li><a href="../media/computeCaptionsManifest.html">computeCaptionsManifest</a></li>
        <li><a href="../media/computeChannel.html">computeChannel</a></li>
        <li><a href="../media/computeCommentsList.html">computeCommentsList</a></li>
        <li><a href="../media/computeManifests.html">computeManifests</a></li>



</ol>

  </div><!--/.sidebar-offcanvas-left-->

  <div id="dartdoc-sidebar-right" class="sidebar sidebar-offcanvas-right">
  </div><!--/.sidebar-offcanvas-->

</main>

<footer>
  <span class="no-break">
    yuuna
      2.8.0+93
  </span>

  
</footer>



<script src="../static-assets/highlight.pack.js?v1"></script>
<script src="../static-assets/docs.dart.js"></script>



</body>

</html>

